/*
 * Encog(tm) Examples v2.4
 * http://www.heatonresearch.com/encog/
 * http://code.google.com/p/encog-java/
 * 
 * Copyright 2008-2010 by Heaton Research Inc.
 * 
 * Released under the LGPL.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 * 
 * Encog and Heaton Research are Trademarks of Heaton Research, Inc.
 * For information on Heaton Research trademarks, visit:
 * 
 * http://www.heatonresearch.com/copyright.html
 */

package mtamarket;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;

import org.encog.ml.data.market.MarketDataDescription;
import org.encog.ml.data.market.MarketDataType;
import org.encog.ml.data.market.MarketMLDataSet;
import org.encog.ml.data.market.loader.MarketLoader;
import org.encog.ml.data.market.loader.YahooFinanceLoader;
import org.encog.ml.data.temporal.TemporalDataDescription;
import org.encog.ml.data.temporal.TemporalMLDataSet;
import org.encog.ml.data.temporal.TemporalPoint;
import org.encog.neural.networks.BasicNetwork;
import org.encog.neural.networks.layers.BasicLayer;
import org.encog.persist.EncogDirectoryPersistence;
import org.encog.util.simple.EncogUtility;

/**
 * Build the training data for the prediction and store it in an Encog file for
 * later training.
 * 
 * @author jeff
 * 
 */
public class MarketBuildTraining {

	public static void generate(File dataDir, Config config) {

		double[][] data = readInData(config);
		
		// create a network
		final BasicNetwork network = EncogUtility.simpleFeedForward(
				data[0].length, 
				Config.HIDDEN1_COUNT, 
				Config.HIDDEN2_COUNT, 
				config.numberOfForecasts, 
				true);	

		// save the network and the training
		EncogDirectoryPersistence.saveObject(new File(dataDir,Config.NETWORK_FILE), network);
	}
	
	//this method reads in the data from the csv
	public static double[][] readInData(Config config){
		
		System.out.println("\n\nreading in data (" + config.DATA_FILENAME + ")...\n");
		
		double[][] data = null;
		
		try{
			  FileInputStream fstream = new FileInputStream(Config.DATA_FILENAME);
			  
			  // Get the object of DataInputStream
			  DataInputStream in = new DataInputStream(fstream);
			  BufferedReader br = new BufferedReader(new InputStreamReader(in));
			  String strLine;
			  
			  ArrayList<Double[]> a = new ArrayList<Double[]>();
			  
			  int begin = 0;
			  int count = 0;
			  
			  String[] lineStrings;
			  Double[] lineNums = null;
			  
			  //Read File Line By Line
			  while ((strLine = br.readLine()) != null)   {

				  try{
					  
					  String seperator = null;
					  
					  if(strLine.contains(",")){
						  seperator = ",";
					  }
					  
					  if(strLine.contains(";")){
						  seperator = ";";
					  }
					  
					  
					  count = 0;
					  
					  
					  
					  lineStrings = strLine.split(seperator);
					  
					  lineNums = new Double[lineStrings.length];
					  
					  for(String s : lineStrings){
						  if(s.length() != 0){
							  lineNums[count++] = Double.parseDouble(s);
						  }else{
							  lineNums[count++] = 0.0;
						  }
					  }
					  
					  a.add(lineNums);
					  
				  }catch(NumberFormatException e){
					  System.out.println("Couldn't parse double.  Maybe a header row?");
				  }
			  }
			  
			  count = 0;
			  int innerCount = 0;
			  
			  data = new double[a.size()][lineNums.length];
			  
			  //move data from arraylist to array
			  for(Double[] d : a){
				  for(Double dbl : d){
					  data[count][innerCount++] = dbl;
				  }
				  innerCount = 0;
				  count++;
			  }

			  //Close the input stream
			  br.close();
			  in.close();
			  fstream.close();
			  
			  config.rawData = data;
			  
		}catch (Exception e){//Catch exception if any
			  System.err.println("Error: " + e.getClass().toString() + ": " + e.getMessage());
			  System.exit(1);
		}
		
		config.transformedData = percentChange(data);
		
		return config.transformedData;
	}
	
	public static double[][] percentChange(double[][] data){
		double[][] toReturn = new double[data.length - 1][data[0].length];
		
		int darryCount = 0;
		
		int count = 0;
		
		for(double[] darray : toReturn){
			for(double d : darray){
				
				if(data[darryCount][count] != 0){
					toReturn[darryCount][count] = (data[darryCount + 1][count] - data[darryCount][count]) / data[darryCount][count];
				}else if(data[darryCount + 1][count] == 0){
					toReturn[darryCount][count] = 0;
				}else{
					toReturn[darryCount][count] = 1;
				}
				
				
				count++;
			}
			count = 0;
			darryCount++;
		}
		
		return toReturn;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
}
